
#ifndef __HEM_PORT_H__
#define __HEM_PORT_H__
#include <stdint.h>
#include "sys_can.h"
#include "hem_common.h"
#include "hems_can_def.h"

#define SPI_FLASH_CS_PORT GPIOA
#define SPI_FLASH_CS_PIN GPIO_PIN_15

#define SPI_FLASH_SCK_PORT GPIOC
#define SPI_FLASH_SCK_PIN GPIO_PIN_10

#define SPI_FLASH_SI_PORT GPIOC
#define SPI_FLASH_SI_PIN GPIO_PIN_11

#define SPI_FLASH_SO_PORT GPIOC
#define SPI_FLASH_SO_PIN GPIO_PIN_12

#define HEM_AI_COM_5V_NUM   8//8路ADC，0~5V采样（复用电流采样）
#define HEM_AI_COM_10V_NUM  8//8路ADC，0~10V采样（复用电路采样）
#define HEM_AI_RES          2//2路ADC，0~10V采样（复用电阻采样）
#define HEM_DPI_NUM         8//8路DI和PI复用端口
#define HEM_DIHL_NUM        8//8路DIH和DIL复用端口
#define HEM_PIC_NUM         0
#define HEM_PIF_NUM         0
#define HEM_DO_COM_NUM      18//18路普通DO输出端口

#define HEM_AO_NUM          3//3路AO输出，其中一路输出固定5V/10V（二选一）；
#define HEM_NORMAL_PWM      2//普通PWM
#define HEM_PWMI_NUM        12 //PWMI恒流输出

#define HEM_PWM_NUM     (HEM_NORMAL_PWM + HEM_PWMI_NUM) //前两个是普通PMW，后12个是PWMI
#define HEM_DO_NUM      (HEM_DO_COM_NUM + HEM_NORMAL_PWM + HEM_PWMI_NUM)       //18路普通DO + 2路PWM和DO复用，12路DO/PWM/PWMI复用
#define HEM_AI_COM_NUM  (HEM_AI_COM_5V_NUM + HEM_AI_COM_10V_NUM) // 普通AI数量
#define HEM_AI_NUM      (HEM_AI_COM_NUM + HEM_AI_RES)   // 16 ai（电压电流） + 2 ai（电阻电压），前16路是普通AI(电压电流采样)，第16，17为电压电阻采样，
#define HEM_IN_PORT_NUM (HEM_AI_COM_NUM + HEM_AI_RES + HEM_DIHL_NUM + HEM_DPI_NUM)
#define HEM_DI_NUM      (HEM_AI_COM_NUM + HEM_AI_RES + HEM_DIHL_NUM + HEM_DPI_NUM)

extern void ai_select(uint8_t ch);
extern void wireless_select_out(uint8_t ch, uint8_t ival);
extern uint8_t get_pi_value(uint32_t ch);
extern void hem_adc_init(void);
enum AI_CHANNEL {
  AIU0,
  AIU1,
  AIU2,
  AIU3,
  AIU4,
  AIU5,
  AIU6,
  AIU7,
  AIU8,
  AIU9,
  PWMi0,
  PWMi1,
  PWMi2,
  PWMi3,
  PWMi4,
  PWMi5,
  AI_CH_NUM = 16,
};

enum IN_MODE {
  IN_MODE_5V = 0u,
  IN_MODE_36V,
  IN_MODE_20MA,
  IN_MODE_30K,
  IN_MODE_DIH,
  IN_MODE_DIL
};

enum AI_PWMI_CHANNEL {
  PWMI0 = 0u,
  PWMI1,
  PWMI2,
  PWMI3,
  PWMI4,
  PWMI5,
  PWMI6,
  PWMI7,
  PWMI8,
  PWMI9,
  PWMi10,
  PWMi11,
  PWMI_CH_NUM,
};
enum wireless_out_port{
  eTx,
  eRx,
  eNss,
  eReset,
};
enum AI_VOL_CHANNEL {
  U0,
  U1,
  U2,
  U3,
  U4,
  U5,
  U6,
  U7,
  U8,
  U9,
  AU_CH_NUM,
};

extern const size_t hem_pin_count;
extern const size_t rcu_periph_count;

/**
 * @brief 参数结构体
 */
typedef struct hem_config 
{
	uint32_t config_ok;                  //参数写入成功标志，固定值0xaa55
  uint32_t node_type;                  //忽略，他用，不能删除
  uint32_t node_id;                    //忽略，他用，不能删除
  uint32_t baudrate[2];                //CAN波特率，因boot程序读取存储的CAN波特率，
                                       //该参数和上面三个参数不能更改，否则CAN波特率不能掉电保存；
  uint32_t can_terminal_resistor[2];   //CAN终端电阻设置，0：禁止终端电阻，1：使能终端电阻
  uint32_t in_mode[HEM_IN_PORT_NUM];   //输入端口配置
  uint32_t pwm_freq[6];                //PWM波特率设置，请参考PWM初始化函数
  uint32_t pwmi_kp100;                 //PID参数设置，Kp
  uint32_t pwmi_ki100;                 //PID参数设置，Ki
  uint32_t pwmi_kd100;                 //PID参数设置，Kd
} hem_config_t;

extern int32_t hem_config_save(hem_config_t *p_config);
extern int32_t hem_config_load(hem_config_t *p_config);
extern hem_config_t g_config;
typedef struct io
{
#if HEM_AI_NUM > 0
  uint32_t ai[HEM_AI_NUM]; 
  uint32_t inmode[HEM_IN_PORT_NUM];/*输入端口配置*/
#endif
#if HEM_DI_NUM > 0
  uint32_t di[HEM_DI_NUM];
#endif
#if HEM_DPI_NUM > 0
  uint32_t pi[HEM_DPI_NUM];
  uint32_t pic[HEM_DPI_NUM];
#endif
#if HEM_DO_NUM > 0
  uint32_t dout[HEM_DO_NUM];
#endif
#if HEM_AO_NUM > 0
  uint32_t ao[HEM_AO_NUM];
#endif
#if HEM_PWM_NUM > 0
  uint32_t pwm[HEM_PWM_NUM];
#endif
#if HEM_PWMI_NUM > 0
  uint32_t pwmi[HEM_PWMI_NUM];
#endif
#if HEM_PWMI_NUM > 0
  uint32_t ai_pwmi[HEM_PWMI_NUM];
#endif
}io_t;

enum OUT_DO
{
  OUT_DO_0,
  OUT_DO_1,
  OUT_DO_2,
  OUT_DO_3,
  OUT_DO_4,
  OUT_DO_5,
  OUT_DO_6,
  OUT_DO_7,
  OUT_DO_8,
  OUT_DO_9,
  OUT_DO_10,
  OUT_DO_11,
  OUT_DO_14,
  OUT_DO_15,
  OUT_DO_16,
  OUT_DO_17,
  OUT_DO_18,
  OUT_DO_19,
  OUT_DO_NUM,
};

extern uint8_t g_pca9555_ch0_out;

void hem_hardware_module_init(void);
/**
 * @brief DO输出
 * [param in] ch 0~17 分别对应Q00~Q7
 * [param in] ival 1:打开DO输出；0：关闭DO输出
 */
extern void do_out(uint32_t ch, uint32_t ival);

/**
 * @brief 获取DI输入值
 * [param in] ch 通道号，0-I00;1-I01;...;15-I15; (0~15，分布对应IN00~IN15端口，电压电流采样)
 *                      16-IN16;17-I17;         (16~17,分别对应IN16~IN17端口，电压电阻采样)
 *                      18-IN18;...;25-IN25;    (18~25,分别对应IN18~IN25端口，DIH和DIL)
 *                      26-IN26;...;33-IN33;    (26~33,分别对应IN26~IN33端口，DIH和PI)
 * [param out] 1-有效；0-无效； 
 *                 
 */
extern uint8_t di_get_value(uint32_t ch);
/**
 * @brief 通信指示灯控制
 * [param in] data LED_ON:LED亮；0：LED熄灭
 */
void led_can(uint32_t data);
/**
 * @brief 状态指示灯控制
 * [param in] data LED_ON:LED亮；0：LED熄灭
 */
extern void led_status(uint32_t data);
/**
 * @brief 错误指示灯控制
 * [param in] data LED_ON:LED亮；0：LED熄灭
 */
extern void led_error(uint32_t data);
/**
 * @brief PWM初始化
 * [param in] freq0 -端口PWMi24/PWMi25/PWMi26/PWMi27的频率设置
 * [param in] freq1 -端口PWMi22/PWMi23/PWMi28/PWMi29的频率设置
 * [param in] freq2 -端口PWMi20/PWMi21的频率设置
 * [param in] freq3 -端口PWMi30的频率设置
 * [param in] freq4 -端口PWMi31的频率设置
 * [param in] freq5 -端口PMW18/PWM19的频率设置
 */
extern void PWM_Init(uint32_t freq0, uint32_t freq1, uint32_t freq2,uint32_t freq3,uint32_t freq4,uint32_t freq5);
/**
 * @brief AO输出
 * [param in] ch: 0~1;连续模拟量输出
 *            ch: 2;固定电压输出，5V/10V可配置
 * [param in] value:范围0~5000mV, ch = 0,0~5V连续输出
 *                  范围0~10000mV,ch = 1,0~10V连续输出
 *                  单位mV,       ch = 2;0<value<=6000,输出5V；6500<value,输出10V；
 */
extern void drv_dac_set_ao(uint8_t ch,uint32_t value);



/**
 * @brief 控制器复位，用于CAN升级
 */
extern void drv_System_Reset(void);

extern void drv_pca9555_out(void);

extern void node_config_init(hem_config_t *config);
extern void Main_pca9555_init(void);

/**
 * @brief 输入端口配置自动更新
 */
extern void port_configure_run(void);


void Main_PF15_Config(void);
#endif
